﻿using Microsoft.SharePoint;
using SharepointCommon;
using System;
using System.Collections.Generic;
using System.Linq;

namespace Uportal.Shp.Core.Common
{
    public class PermitManager : IDisposable
    {
        NLogLogger _logger = new NLogLogger(@"c:\Temp\Logs\Uportal.PermitManager_${shortdate}.log");
        private SPListItem _item;

        public PermitManager(SPListItem item)
        {
            _item = item;
        }
        public PermitManager(Item item)
        {
            var list = item.ParentList;

            using (var wf = WebFactory.Elevated(list.SiteId, list.WebId))
            {
                _item = wf.Web.Lists[list.Id].GetItemById(item.Id);
            }
        }

        public void AddPrivatePermissions(IEnumerable<SPPrincipal> principals)
        {
            ClearPermissions();
            foreach (var member in principals)
            {
                AddPermission(member, SPRoleType.Contributor, true);
            }
        }

        public void AddPermission(SPPrincipal member, SPRoleType roleType, bool breakPermissions)
        {
            if (roleType == SPRoleType.None) return;

            // проверка на наличие для принципала нужного разрешения
            var roleAssignment = GetByPrincipal(member);
            if (roleAssignment != null)
                if (roleAssignment.RoleDefinitionBindings.Cast<SPRoleDefinition>().Any(x => x.Type == roleType))
                    return;

            EnsureBreakPermissions(breakPermissions);

            // добавление разрешения
            var roleDef = member.ParentWeb.RoleDefinitions.GetByType(roleType);
            var newAssignment = new SPRoleAssignment(member);

            bool @unsafe = _item.Web.AllowUnsafeUpdates;
            _item.Web.AllowUnsafeUpdates = true;

            newAssignment.RoleDefinitionBindings.Add(roleDef);
            _item.RoleAssignments.Add(newAssignment);

            _item.Web.AllowUnsafeUpdates = @unsafe;
        }

        public void ClearPermissions()
        {
            EnsureBreakPermissions(false);

            bool @unsafe = _item.Web.AllowUnsafeUpdates;
            _item.Web.AllowUnsafeUpdates = true;
            for (int i = _item.RoleAssignments.Count - 1; i >= 0; i--)
                _item.RoleAssignments.Remove(i);
            _item.Web.AllowUnsafeUpdates = @unsafe;
        }

        public void EnsureBreakPermissions(bool copyRoleAssignments)
        {
            if (!_item.HasUniqueRoleAssignments)
            {
                bool @unsafe = _item.Web.AllowUnsafeUpdates;
                _item.Web.AllowUnsafeUpdates = true;
                _item.BreakRoleInheritance(copyRoleAssignments);
                _item.Web.AllowUnsafeUpdates = @unsafe;
            }
        }
        
        private SPRoleAssignment GetByPrincipal(SPPrincipal member)
        {
            return this._item.RoleAssignments.Cast<SPRoleAssignment>().FirstOrDefault(x => x.Member.ID == member.ID);
        }
        
        public void Dispose()
        {
            throw new NotImplementedException();
        }
    }
}
